#pragma once

#include <string>
#include <vector>
#include <filesystem>
#include <functional>

namespace alexcr4ckpentest::utils
{
  template<typename T, typename U>
    requires requires(T t) { { std::cbegin(t) }; { std::cend(t) }; }
  constexpr auto find(const T& container, U&& value) noexcept
  {
    return std::find(container.cbegin(), container.cend(), std::forward<U>(value)) != container.cend();
  }
}



class RecursiveImageScanner final
{
private:
  using scan_finished_callback = std::function<void(std::vector<std::filesystem::path>&)>;

public:
  RecursiveImageScanner() noexcept;
  RecursiveImageScanner(std::string_view initial_path);

  RecursiveImageScanner(const RecursiveImageScanner&) = delete;
  RecursiveImageScanner(RecursiveImageScanner&&) = delete;
  RecursiveImageScanner& operator=(const RecursiveImageScanner&) = delete;
  RecursiveImageScanner& operator=(RecursiveImageScanner&&) = delete;

  inline void set_initial_path(std::string_view initial_path)
  { initial_path_ = initial_path; }

  void add_image_file_extension(std::string_view file_extension);
  void start_scan(scan_finished_callback scan_finished_callback);

private:
  std::string initial_path_;
  std::vector<std::filesystem::path> detected_images_;

  static std::vector<std::string> image_file_extensions_;

  inline bool is_image(const std::filesystem::path& filename) noexcept
  { return alexcr4ckpentest::utils::find(image_file_extensions_, filename); }
};
